package com.cskaoyan.until;


import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class FileUploadUtils {
    private static final String LOCAL_ADR = "http://localhost:8083";

    public static Map<String, Object> parseRequest(HttpServletRequest request) {

        Map<String, Object> map = new HashMap<String, Object>();

        //设置大文件缓存使用的临时仓库；
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletContext servletContext = request.getServletContext();
        File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
        factory.setRepository(repository);

        //获得一个文件上传的处理器；
        ServletFileUpload upload = new ServletFileUpload(factory);

        //文件名乱码；
        upload.setHeaderEncoding("utf-8");

        //解析请求；
        try {
            List<FileItem> fileItems = upload.parseRequest((RequestContext) request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {
                    //是表单元素，非文件；
                    processFormField(fileItem, map);
                } else {
                    //是文件；
                    processUploadedFile(fileItem, map, request);
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

        return map;
    }

    private static void processUploadedFile(FileItem fileItem, Map<String, Object> map, HttpServletRequest request) {
        String fieldName = fileItem.getFieldName();
        String filename = fileItem.getName();

        //未避免文件名重复；
        String uuid = UUID.randomUUID().toString();
        filename = uuid + "_" + filename;

        //根据文件名划分多级目录；
        int hashCode = filename.hashCode();
        char[] chars = Integer.toHexString(hashCode).toCharArray();

        //相对于应用根目录；
        String basePath = "/static/image";
        for (char aChar : chars) {
            basePath = basePath + "/" + aChar;
        }
        String relativePath = basePath + "/" + filename;//文件的相对地址；
        String realPath = request.getServletContext().getRealPath(relativePath);
        File file = new File(realPath);

        //判断父级目录是否存在；
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        try {
            fileItem.write(file);
            map.put(fieldName, LOCAL_ADR + relativePath);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void processFormField(FileItem fileItem, Map<String, Object> map) {
        String inputName = fileItem.getFieldName();
        try {
            String inputValue = fileItem.getString("utf-8");
            map.put(inputName, inputValue);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}
